import mx.events.EventDispatcher;

import org.molamil.acto.commands.Command;
import org.molamil.acto.commands.CommandContext;
import org.molamil.acto.commands.CommandRequest;
import org.molamil.acto.commands.CommandResult;
import org.molamil.acto.core.EventConstants;
import org.molamil.acto.core.Logger;
import org.molamil.commons.EventUtil;
import org.molamil.acto.commands.CommandsConf;

import mx.utils.Delegate;

/**
 * @author Jorge Hernandez
 */
class org.molamil.acto.commands.CommandMaster implements Command {
	
		// Constants
	
	private static var EXECUTION_DELAY:Number = 10;
	
	
	// Properties
	
	private static var log:Logger = Logger.getLogger("CommandMaster");
	
	private var _context:CommandContext;
	private var _request:CommandRequest;	private var _cmd:Command;
	private var _result:CommandResult;	private var isExecuted:Boolean;	private var edIntervalId:Number;
	
	
	// Constructor
	
	public function CommandMaster() {
		EventDispatcher.initialize(this);
		isExecuted = false;
	}
	
	
	// Functions
	
	public function dispatchEvent(eventObj:Object):Void {}
	public function addEventListener(event:String, handler):Void {}
	public function removeEventListener(event:String, handler):Void {}
	
	public function execute(request:CommandRequest):CommandResult {
		
		log.debug("execute()");
		
		if (isExecuted)
			return null;
			
		if (request != null)
			_request = request;
			
		EventUtil.propagate(_cmd, this, EventConstants.COMMAND_EXECUTE_START);
		EventUtil.propagate(_cmd, this, EventConstants.COMMAND_EXECUTE_COMPLETE);		EventUtil.propagate(_cmd, this, EventConstants.COMMAND_EXECUTE_ERROR);
		
		_cmd.addEventListener(EventConstants.COMMAND_EXECUTE_START, Delegate.create(this, onCmdExecuteStart));		_cmd.addEventListener(EventConstants.COMMAND_EXECUTE_COMPLETE, Delegate.create(this, onCmdExecuteComplete));		_cmd.addEventListener(EventConstants.COMMAND_EXECUTE_ERROR, Delegate.create(this, onCmdExecuteError));
		
		if (CommandsConf.isExecutionDelay) {
			edIntervalId = setInterval(Delegate.create(this, doExecute), EXECUTION_DELAY);
		} else {
			doExecute();
		}
		
		return _result;
		
	}
	
	private function doExecute():Void {
		clearInterval(edIntervalId);
		_result = _cmd.execute(_request);
		isExecuted = true;
	}
	
	private function onCmdExecuteStart(eventObject:Object):Void {
		log.info("onCmdExecuteStart, name = " + eventObject.name);
	}
	
	private function onCmdExecuteComplete(eventObject:Object):Void {
		log.info("onCmdExecuteComplete, nam e= " + eventObject.name);
		log.info("onCmdExecuteComplete, result = " + eventObject.result);
	}
	
	private function onCmdExecuteError(eventObject:Object):Void {
		log.warning("onCmdExecuteError, name = " + eventObject.name);		log.warning("onCmdExecuteError, result = " + eventObject.result);
	}

	
	// Getter/Setter
	
	public function get context():CommandContext {
		return _context;
	}
	
	public function set context(context:CommandContext):Void {
		_context = context;
	}
	
	public function get request():CommandRequest {
		return _request;
	}
	
	public function set request(request:CommandRequest):Void {
		_request = request;
	}
	
	public function get cmd():Command {
		return _cmd;
	}
	
	public function set cmd(cmd:Command):Void {
		_cmd = cmd;
	}
	
	public function get result():CommandResult {
		return _result;
	}
	
	
}
